﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SystemAnalizer.Common;
using SystemAnalizer.Models;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows;

namespace SystemAnalizer.ViewModel
{
    public class CreateSystemViewModel
    {
        private int systemsize;
        private NonPeriodicMatrixModel non_periodicmatrix;
        private PeriodicMatrixModel periodicmatrix;
        private bool is_periodic;
        private int number_disc;
        private double H_st;
        private double centeraprox;

        public CreateSystemViewModel(bool isperiodic)
        {
            this.is_periodic = isperiodic;
            CommandsLoader(); 
        }

        private void CommandsLoader()
        {
            InsertSystemCommand = new ViewModelCommand(InsertSystem, (o) => { return true; });
        }

        public bool IsPeriodic
        {
            get { return !this.is_periodic; }
        }

        // InsertSystem
        private void InsertSystem(object param)
        {
            if (this.is_periodic)
                InsertPeriodicSystem(param);
            else
                InsertNonPeriodicSystem(param); 
        }

        public void InitContainerwithDiscretes(StackPanel pnl)
        {
            if (this.is_periodic)
                this.periodicmatrix.DiscretofMatrixtoContainerAdder(pnl);
            else
                this.non_periodicmatrix.DiscretofMatrixtoContainerAdder(pnl);
        }

        public void InitContainerwithSystemInfo(StackPanel pnl)
        {
            if (this.is_periodic)
                this.periodicmatrix.SystemInserValtoContainerAdder(pnl);
            else
                this.non_periodicmatrix.SystemInserValtoContainerAdder(pnl);
        }

        public SystemModel GetSystem
        {
            get
            {
                if (this.periodicmatrix != null)
                    return this.periodicmatrix;
                if (this.non_periodicmatrix != null)
                    return this.non_periodicmatrix;
                return null;
            }
        }

        // InsertPeriodicSystem
        private void InsertPeriodicSystem(object param)
        {
            if (!ValidateInput())
                return;
            CreateSystem cursys = param as CreateSystem;
            this.periodicmatrix = new PeriodicMatrixModel(this.number_disc,this.systemsize);
            Grid gridval = cursys.SystemValuesgrd;
            if (!ValidatePeriodicSystemInput(gridval))
                return;
            cursys.DialogResult = true;
            cursys.Close();
        }

        // InsertNonPeriodicSystem
        private void InsertNonPeriodicSystem(object param)
        {
            if (!ValidateInput())
                return;
            CreateSystem cursys = param as CreateSystem;
            this.non_periodicmatrix = new NonPeriodicMatrixModel(this.number_disc, this.systemsize);
            
            Grid gridval = cursys.SystemValuesgrd;

            if (!ValidateNonPeriodicSystemInput(gridval))
                return;
            cursys.DialogResult = true;
            cursys.Close();
        }

        private bool ValidateNonPeriodicSystemInput(Grid grid)
        {
            bool isok = true;
            TextBox temptxb = new TextBox();

            string[,] gridval = new string[this.systemsize, this.systemsize];
            int i = 0;
            int j = 0;
            foreach (var itm in grid.Children)
            {
                if (itm is TextBox)
                    temptxb = (TextBox)itm;

                if (Grid.GetRow(temptxb) == i && Grid.GetColumn(temptxb) == j)
                    gridval[i, j] = temptxb.Text;
                j++;
                if (j == this.systemsize)
                {
                    j = 0;
                    i++;
                }
            }

            this.non_periodicmatrix.initMatrixInput(gridval);
            isok = this.non_periodicmatrix.startMakeDiscretes();

            return isok;
        }

        private bool ValidatePeriodicSystemInput(Grid grid)
        {
            bool isok = true;
            TextBox temptxb = new TextBox();

            string[,] gridval = new string[this.systemsize, this.systemsize];
            int i = 0;
            int j = 0;
            foreach (var itm in grid.Children)
            {
                if (itm is TextBox)
                    temptxb = (TextBox)itm;

                if (Grid.GetRow(temptxb) == i && Grid.GetColumn(temptxb) == j)
                    gridval[i, j] = temptxb.Text;
                j++;
                if (j == this.systemsize)
                {
                    j = 0;
                    i++;
                }
            }

            this.periodicmatrix.initMatrixInput(gridval);
            isok = this.periodicmatrix.startMakeDiscretes();
   
            return isok;
        }

        private bool ValidateInput()
        {
            bool isok = true;
            try
            {
               this.centeraprox = Convert.ToDouble(this.CenterAproxVal);
            }
            catch(FormatException ex)
            {
                ErrorDialogs.PrintErrorDialog("Invalid input for Centerofapproximation");
                isok = false;
            }

            try
            {
                this.H_st = Convert.ToDouble(this.HStepVal);
            }
            catch (FormatException ex)
            {
                ErrorDialogs.PrintErrorDialog("Invalid input for step");
                isok = false;
            }
            if (this.H_st == 0)
            {
                ErrorDialogs.PrintErrorDialog("Invalid input for step");
                isok = false;
            }

            try
            {
                this.number_disc = Convert.ToInt32(this.NumberDiscrVal);
            }
            catch
            {
                ErrorDialogs.PrintErrorDialog("Invalid input for step");
                isok = false;
            }
 
            return isok;
        }

 

        #region commands 
        public ICommand InsertSystemCommand { get; set; }
       
       
      
        #endregion   // commands
        private string center_aprox = "0";
        private string h_step = "1";
        
        public string SystemSizeVal { get; set; }
        public string NumberDiscrVal { get; set; }
        public string CenterAproxVal 
        {
            get
            {
                return this.center_aprox;
            }
            set
            {
                this.center_aprox = value;
            }
        }
        public string HStepVal
        {
            get
            {
                return this.h_step;
            }
            set
            {
                this.h_step = value;
            }
        }
       

        public void SystemSizeValidate(string text,Grid grd)
        {
            grd.Children.Clear();
            try
            {
                this.systemsize = Convert.ToInt32(text);
            }
            catch
            {
                ErrorDialogs.PrintErrorDialog(CommonString.Insert_Valid_integer);
                this.systemsize = 0;
                return;
            }
            if (this.systemsize < 0)
            {
                ErrorDialogs.PrintErrorDialog(CommonString.Insert_Valid_integer);
                return;
            }
            SystemModel.VisualMatrixMaker(this.systemsize, grd);        
        }
    }
}
